package com.jacky.ocr_plugin.camera;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.hardware.Camera;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.OrientationEventListener;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.ViewGroup;
import android.widget.FrameLayout;

import com.jacky.util.OcrLogger;
import com.jacky.util.FilePathUtils;
import com.jacky.util.OnOcrRectCallback;
import com.jacky.util.OnOcrRectErrorCallback;
import com.yunmai.cc.idcard.controler.OcrConstant;
import com.yunmai.cc.idcard.controler.OcrManager;
import com.yunmai.cc.idcard.vo.IdCardInfo;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.util.HashMap;
import java.util.Iterator;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

/**
 * ocr识别控件
 * Created by liaoyacheng on 2021/9/13.
 */
public class CustomOcrRectView extends FrameLayout implements SurfaceHolder.Callback {

    public CustomOcrRectView(@NonNull Context context) {
        super(context);
        initView(context);
    }

    public CustomOcrRectView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initView(context);
    }

    public CustomOcrRectView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView(context);
    }

    private final static int START_AUTOFOCUS_TIME = 800;//500
    private final static int TAKE_PREVIEW_DATA_TIME = 2500; //1500
    private final static int REPEAT_AUTOFOCUS_TIME = 1500; //1500
    public boolean mCameraError;
    private OnOcrRectCallback mCallback;
    private OnOcrRectErrorCallback mErrorCallback;
    private SurfaceView mSurfaceView;
    private OcrCameraManager mCameraManager;
    private Rect mUsedRect;
    private Context mContext;
    private SurfaceHolder mSurfaceHolder;
    private OcrManager mOcrManager;
    private String mOcrImgFilePath;
    private String mOcrHeadImgFilePath;
    private boolean mAutoFoucs = true;
    private boolean mUseOrientation;
    private MyOrientationEventListener mOrientationListener;
    //flutter定义参数，是否进行扫描、图片保存时是否旋转、扫描类型？-目前无用
    private boolean scanEnable = true;
    private boolean takePhotoRotated = true;
    private boolean portraitToLandscape = true;
    private int type = 0;
    private Rect overlayRec;
    ///图片拍照的线程处理
    private final Handler mMainHandler = new Handler(Looper.getMainLooper());
    private HandlerThread mThread;
    private Handler mThreadHandler;
    private Runnable mThreadRun;
    private boolean isTakePictureFromPreview;
    private boolean isTakePictureWithRect;
    //正在处理拍照的数据，防止多次处理数据返回
    private boolean mHandlingData = false;

    /**
     * 设置识别结果回调
     */
    public void setOcrRectCallback(OnOcrRectCallback callback) {
        this.mCallback = callback;
    }

    public void setOcrRectErrorCallback(OnOcrRectErrorCallback callback) {
        this.mErrorCallback = callback;
    }

    public void setParams(HashMap<String,Object> params){
        OcrLogger.d("setParams",params);
        if(params.containsKey("scanEnable")) {
            Boolean en = (Boolean) params.get("scanEnable");
            if(en != null) scanEnable = en;
        }
        if(params.containsKey("type")) {
            Integer t = (Integer) params.get("type");
            if(t != null) type = t;
        }
        if(params.containsKey("takePhotoRotated")) {
            Boolean t = (Boolean) params.get("takePhotoRotated");
            if(t != null) takePhotoRotated = t;
        }
        if(params.containsKey("ocrImgPath")) {
            String path = (String) params.get("ocrImgPath");
            if(path != null) mOcrImgFilePath = path;
        }
        if(params.containsKey("ocrHeadPath")) {
            String path = (String) params.get("ocrHeadPath");
            if(path != null) mOcrHeadImgFilePath = path;
        }
        //竖向转横向识别ocr：如手机竖向页面，转横向识别传true；pad是竖向识别传 false
        if(params.containsKey("portraitToLandscape")) {
            Boolean can = (Boolean) params.get("portraitToLandscape");
            if(can != null) {
                portraitToLandscape = can;
                mUsedRect = getViewfinder(overlayRec,portraitToLandscape);
            }
        }
        if(params.containsKey("androidUseImageOrientation")){
            setUseImageOrientation((Boolean) params.get("androidUseImageOrientation"));
        }
        if(params.containsKey("cameraGravity")){
            Integer gravity = (Integer) params.get("cameraGravity");
            if(gravity != null){
                switch (gravity){
                    case 1: updateParams(Gravity.TOP);break;
                    case 2: updateParams(Gravity.CENTER);break;
                    case 3: updateParams(Gravity.BOTTOM);break;
                }
            }
        }
    }

    private void updateParams(int gravity){
        if(mSurfaceView == null)return;
        FrameLayout.LayoutParams pp = (LayoutParams) mSurfaceView.getLayoutParams();
        //Preview预览的宽高需要倒置
        float r = mCameraManager.getPreviewWidth() * 1f/ mCameraManager.getPreviewHeight();
        pp.height = (int) (CustomOcrRectView.this.getMeasuredWidth() * r);
        pp.gravity = gravity;
        mSurfaceView.setLayoutParams(pp);
    }

    private void initView(Context context) {
        mContext = context;
        mSurfaceView = new SurfaceView(context);
        mSurfaceView.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        addView(mSurfaceView);
        //camera CameraManager 改为OcrCameraManager
        mCameraManager = new OcrCameraManager(context.getApplicationContext(), mHandler);
        mCameraManager.setPreviewCallback(previewCallback);
        mOrientationListener = new MyOrientationEventListener(context);
        mCameraOpenThread.start();
        try {
            mCameraOpenThread.join();
            mCameraOpenThread = null;
        } catch (Exception e) {
            e.printStackTrace();
            mCameraError = true;
        }
        if (mCameraError) {
            error("1", "照相机未启动！");
            //finish();
        }
        setParameters();
    }

    private final Camera.PreviewCallback previewCallback = new Camera.PreviewCallback() {
        public void onPreviewFrame(byte[] data, Camera camera) {
            handleData(data);
        }
    };

    public void setRecognizeRect(Rect recognizeRect) {
        mUsedRect = getViewfinder(recognizeRect,portraitToLandscape);
    }
    

    /**
     * 设置ocr识别图片的保存路径
     */
    public void setOcrImgFilePath(String filePath, String headPath) {
        mOcrImgFilePath = filePath;
        mOcrHeadImgFilePath = headPath;
    }

    public void pause() {
        if (mCameraManager != null)
            mCameraManager.pauseDisplay();
        if(mOrientationListener != null)mOrientationListener.disable();
    }

    public void resume() {
        if (mCameraManager != null){
            if(!(mCameraManager.cameraOpened() && mCameraManager.initDisplay())){
                //重启相机失败，则开启相机 (其他app使用摄像头，返回页面时出现该情况)
                try {
                    mCameraManager.openCamera(mSurfaceHolder);
                    setParameters();
                    mCameraManager.initDisplay();
                    startDecoding();
                } catch (Exception e) {
                    e.printStackTrace();
                    mCameraError = true;
                }
            }
        }
        if(mOrientationListener != null)mOrientationListener.enable();
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        if(mOrientationListener != null)mOrientationListener.enable();
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        if(mOrientationListener != null)mOrientationListener.disable();
    }

    public void close() {
        stopDecoding();
        mHandler.removeCallbacksAndMessages(null);
        if(mOrientationListener != null)mOrientationListener.disable();
        if (mCameraManager != null) {
            mCameraManager.closeCamera();
        }
        if(mThread != null)mThread.quit();
    }

    public void stopDecoding() {
        mHandler.removeMessages(OcrConstant.START_AUTOFOCUS);
        mHandler.removeMessages(OcrConstant.TAKE_PREVIEW_DATA_OK);
    }

    public void startDecoding() {
        stopDecoding();
        mHandler.sendEmptyMessageDelayed(OcrConstant.START_AUTOFOCUS,START_AUTOFOCUS_TIME);
        mHandler.sendEmptyMessageDelayed(OcrConstant.TAKE_PREVIEW_DATA_OK,1500);
    }

    public boolean setTorchFlash(boolean torchFlash) {
        if (mCameraManager != null) {
            if (torchFlash) return mCameraManager.openFlashlight();
            else return !mCameraManager.closeFlashlight();
        }
        return false;
    }


    /**
     * 摄像头 拍照
     */
    public void takePhotoCamera(){
        if (mCameraManager != null) {
            //交由聚焦后处理保存图片
            isTakePictureFromPreview = true;
        }
//        if (mCameraManager != null) {
//            mCameraManager.takePicture(new Camera.PictureCallback() {
//                @Override
//                public void onPictureTaken(byte[] data, Camera camera) {
//                    if(mThread == null || !mThread.isAlive()){
//                        mThread = new HandlerThread("savePicture");
//                        mThread.start();
//                        mThreadHandler  = new Handler(mThread.getLooper());
//                    }
//                    if(mThreadRun != null) mThreadHandler.removeCallbacks(mThreadRun);
//                    //线程处理数据
//                    mThreadRun = new TakePictureRun(data);
//                    mThreadHandler.post(mThreadRun);
//                    //拍一次照片，开启再次预览
//                    mMainHandler.postDelayed(()->mCameraManager.initDisplay(),350);
//                }
//            });
//        }
    }
    /**
     * 摄像头 拍照图片 根据rect进行截取
     */
    public void takePhotoCameraWithRect(){
        if (mCameraManager != null) {
            isTakePictureFromPreview = true;
            isTakePictureWithRect = true;
        }
    }
    private class TakePictureRun implements Runnable{
        private final byte[] data;
        TakePictureRun(byte[] data){
            this.data = data;
        }

        @Override
        public void run() {
            File file = FilePathUtils.getFile(getContext(),mOcrImgFilePath, "ocr_img.jpg");
            String imgFile = file.getAbsolutePath();
            //OcrLogger.d("imgFile",imgFile);
            if(!portraitToLandscape){
                FilePathUtils.savePicture(data,imgFile);
            } else{
                int ro = getImageRotation();
                //图片
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inTempStorage = new byte[100 * 1024];
                options.inPreferredConfig = Bitmap.Config.RGB_565;
                options.inPurgeable = true;
                Bitmap bm = BitmapFactory.decodeByteArray(data,0,data.length,options);
                //缩放比例
                int width = bm.getWidth(),height = bm.getHeight();
                int max = Math.max(width,height);
                float scale = max > 1500 ? (1500f/max) : 0;
                OcrLogger.d("rotation",ro,"scale",scale,"width",width,"height",height);
                //旋转
                Bitmap bm2 = null;
                if(ro != 0 || scale != 0){
                    Matrix m = new Matrix();
                    if(ro != 0) m.setRotate(ro,0,0);
                    if(scale != 0) m.preScale(scale,scale);
                    bm2 = Bitmap.createBitmap(bm,0,0,width,height, m, true);
                    //bm.recycle();//bm 回收后，bm2也回收了
                    bm = bm2;
                }
                FilePathUtils.saveBitmapLimitSize(file, bm, 80);
                bm.recycle();
                if(bm2 != null && !bm2.isRecycled()){
                    bm2.recycle();
                }
            }
            mMainHandler.post(()->handleResultCallback(imgFile));
        }
    }

    /**
     * 拍照的图片，是否使用重力感应旋转图片
     */
    public void setUseImageOrientation(Boolean useOrientation){
        mUseOrientation = useOrientation != null && useOrientation;
    }

    /**
     * 切换摄像头，不知道是否有影响
     */
    public void switchCamera(){
        if(mCameraManager != null && mSurfaceHolder != null){
            mCameraManager.switchCamara(mSurfaceHolder);
        }
    }

    public void checkCameraOpen(){
        if(mCameraManager != null){
            if(mCameraManager.cameraOpened()){
                mCameraManager.openCamera();
            }
            startDecoding();
        }
    }

    private void setParameters() {
        if(mCameraManager.isCameraFacingBack()){
            mCameraManager.setCameraFlashModel(Camera.Parameters.FLASH_MODE_OFF);
        }
        mCameraManager.setViewHeightOrWidthForCameraWidth(portraitToLandscape?getHeight():getWidth());
        mCameraManager.setPreviewSize();
        mCameraManager.setDisplayOrientation();
        int pWidth = mCameraManager.getPreviewWidth();
        int pHeight = mCameraManager.getPreviewHeight();
        if (pWidth == 0 || pHeight == 0) {
            error("1", "照相机未启动！");
            //finish();
            return;
        }
        //宽高比=240:151
//        int outlineHeight = minLength/151 * 151;//比例*151
//        int outlineWidth = minLength/151 * 240;//比例*240
        mSurfaceHolder = mSurfaceView.getHolder();
        mSurfaceHolder.addCallback(this);
        mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

    }

    private void error(String code, String message) {
        OcrLogger.d("ocrRectView", "error code " + code + " message " + message);
        if (mErrorCallback != null)
            mErrorCallback.callback(code, message);
    }

    private void handleData(byte[] data_p){
        if (mOcrManager == null) {
            mOcrManager = new OcrManager(mHandler, mContext);
        }
        if(mUsedRect == null){
            mUsedRect = getViewfinder(new Rect(0,0,getWidth(),getHeight()));
        }
        if(mHandlingData){
            OcrLogger.d("handleData mHandlingData true");
            return;
        }
        if (data_p != null && data_p.length > 0) {
            if(isTakePictureFromPreview){
                onPreviewCallback(data_p);
            }else if(scanEnable){
                //得到需要识别的数据，进行识别
                mOcrManager.recognBC(data_p, mCameraManager.getPreviewWidth()
                        , mCameraManager.getPreviewHeight(), mUsedRect);
            }
            //testForSaveImage(data_p);//测试图片及截取区域的图片
        }
//                    else {
//                        //error("2", "相机出现问题，请重启手机！");
//                    }
        mHandler.sendEmptyMessageDelayed(OcrConstant.START_AUTOFOCUS, START_AUTOFOCUS_TIME);
    }

    @SuppressLint("HandlerLeak")
    private final Handler mHandler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(@NonNull Message msg) {
            switch (msg.what) {
                case OcrConstant.TAKE_PREVIEW_DATA_OK:
                    if (mOcrManager == null) {
                        mOcrManager = new OcrManager(mHandler, mContext);
                    }
                    if(mUsedRect == null){
                        mUsedRect = getViewfinder(new Rect(0,0,getWidth(),getHeight()));
                    }
                    byte[] data_p = (byte[]) msg.obj;
                    if (data_p != null && data_p.length > 0) {
                        if(isTakePictureFromPreview){
                            onPreviewCallback(data_p);
                        }else if(scanEnable){
                            //得到需要识别的数据，进行识别
                            mOcrManager.recognBC(data_p, mCameraManager.getPreviewWidth()
                                    , mCameraManager.getPreviewHeight(), mUsedRect);
                        }
                        //testForSaveImage(data_p);//测试图片及截取区域的图片
                    }
//                    else {
//                        //error("2", "相机出现问题，请重启手机！");
//                    }
                    mHandler.sendEmptyMessageDelayed(OcrConstant.START_AUTOFOCUS, START_AUTOFOCUS_TIME);
                    break;
                case OcrConstant.RECOGN_OK:
                    //识别成功，进行处理数据
                    mHandler.removeMessages(OcrConstant.TAKE_PREVIEW_DATA_OK);
                    mHandler.removeMessages(OcrConstant.START_AUTOFOCUS);
                    String imgFile = FilePathUtils.getFile(getContext(),mOcrImgFilePath, "ocr_img.jpg").getAbsolutePath();
                    String headFile = FilePathUtils.getFile(getContext(),mOcrHeadImgFilePath, "ocr_head.jpg").getAbsolutePath();
                    IdCardInfo idCardInfo = mOcrManager.getResult(imgFile, headFile);
                    try {
                        String card = new String(idCardInfo.getCharInfo(), "gbk");
                        //card最后一个"}"后面是乱码，导致解析不出来
                        String info = card.substring(0, card.lastIndexOf("}") + 1);
                        handleResultCallback(info, imgFile, headFile);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    //让其可以继续识别
                    mHandler.sendEmptyMessageDelayed(OcrConstant.TAKE_PREVIEW_DATA_OK,500);
                    mHandler.sendEmptyMessageDelayed(OcrConstant.START_AUTOFOCUS, START_AUTOFOCUS_TIME);
                    break;
                case OcrConstant.REPEAT_AUTOFOCUS:
                    mCameraManager.autoFoucs();
                    mHandler.sendEmptyMessageDelayed(OcrConstant.REPEAT_AUTOFOCUS, 2000);
                    break;
                case OcrConstant.RECOGN_EG_TIME_OUT:
                    error("3", "引擎过期，请尽快更新！");
                    break;
                case OcrConstant.RECOGN_EG_LICENSE:
                    error("3", "授权失败！");
                    break;
                case OcrConstant.RECOGN_EG_INIT_ERROR:
                    error("3", "引擎初始化失败！");
                    break;
                case OcrConstant.START_AUTOFOCUS:
                    if (mAutoFoucs) {
                        mCameraManager.autoFoucs();
                        mAutoFoucs = false;
                        mHandler.sendEmptyMessageDelayed(OcrConstant.START_AUTOFOCUS, START_AUTOFOCUS_TIME);
                        mHandler.sendEmptyMessageDelayed(OcrConstant.REPEAT_AUTOFOCUS, 1500);
                    } else {
                        mCameraManager.autoFocusAndPreviewCallback();
                    }
                    break;
                case OcrConstant.RECOGN_LINE_IN_RECT:
//                    int restult =  (Integer) msg.obj;
//                    vfCamera.setLineRect(restult);
                    break;
                default:
                    mCameraManager.initDisplay();
                    mHandler.sendEmptyMessageDelayed(OcrConstant.START_AUTOFOCUS, START_AUTOFOCUS_TIME);
                    OcrLogger.d("tag","flutter to android, ocr handler what "+msg.what);
                    //ToastUtil.showMsg("<>"+msg.what);
                    break;
            }
        }

        boolean can = false;
        int count = 0;
        //仅仅用于测试
        private void testForSaveImage(byte[] data_p){
            if(count++ / 8 == 0) can = true;
            if(can){
                can = false;
                FilePathUtils.savePreviewDataToImage(data_p, mCameraManager.getPreviewWidth()
                        , mCameraManager.getPreviewHeight(), mUsedRect,null,null);
            }
        }

    };
    private Rect getViewfinder(Rect rec){
        return getViewfinder(rec,portraitToLandscape);
    }
    ///将屏幕画面的rect区域，转为摄像头画面rect
    private Rect getViewfinder(Rect rec, boolean portraitToLandscape) {
        this.portraitToLandscape = portraitToLandscape;
        if (rec == null) {
            rec = new Rect(0, 0, getWidth(), getHeight());
        }
        overlayRec = rec;
        DisplayMetrics dm = getResources().getDisplayMetrics();
        int w = Math.max(dm.widthPixels,dm.heightPixels);
        int h = Math.min(dm.widthPixels,dm.heightPixels);
        int preW = mCameraManager.getPreviewWidth();
        int preH = mCameraManager.getPreviewHeight();
        float xs = preW / (float) w;
        float ys = preH / (float) h;

        int recH = rec.bottom - rec.top;
        int recW = rec.right - rec.left;
        int width;// = (int) ((rec.bottom - rec.top)*xs);
        int height;// = (int) ((rec.right - rec.left)*ys);
        Rect rect = new Rect();
        int angle = mCameraManager.getCameraAngle();
        //angle = portraitToLandscape ? angle : 0;
        //’代表度，0‘表示摄像头真实方向，90’代表预览方向 90度，w代表宽度，h代表高度
        switch (angle){
            case 90:
                //0‘left = 90’top，0‘top=90’w-90‘right，90’w=0‘h
                //使用xs 还是ys，有0’的left、top决定
                rect.left = (int) (rec.top * xs);//(int) ((getHeight() - rec.bottom) * xs);
                rect.top = (int) ((getWidth() - rec.right) * ys);//(int) (rec.left * ys);
                width = (int) (recH * xs);
                height = (int) (recW * ys);
                break;
            case 180:
                //0‘left = 180’w-180‘right，0‘top=180’h-180‘bottom，180’w=0‘w，180’h=0‘h
                rect.left = (int) ((getWidth() - rec.right) * xs);//(int) ((getWidth() - rec.right) * xs);
                rect.top = (int) ((getHeight() - rec.bottom) * ys);//(int) ((getHeight() - rec.bottom) * ys);
                width = (int) (recW * xs);
                height = (int) (recH * ys);
                break;
            case 270:
                //0‘left = 270’h-270’bottom，0‘top=270‘left，270’w=0‘h，270’h=0‘w
                rect.left = (int) (((getHeight() - rec.bottom)) * xs);//(int) (rec.top* xs);
                rect.top = (int) (rec.left * ys);//(int) ((getWidth() - rec.right) * ys);
                width = (int) (recH * xs);
                height = (int) (recW * ys);
                break;
            case 0:
            default:
                //0‘left = 360‘left,0‘top=360‘top,360’w=0‘w，360’h=0‘
                rect.left = (int) (rec.left * xs);
                rect.top = (int) (rec.top * ys);
                width = (int) (recW * xs);
                height = (int) (recH * ys);
                break;
        }
        rect.right = rect.left + width;
        rect.bottom = rect.top + height;
        //camera居中后 区域应该会有问题
//        OcrLogger.d("tag", "flutter to android,  getCameraAngle "+mCameraManager.getCameraAngle()
//                +" angle "+angle + " xs "+xs + " ys "+ys
//                + "\n left " + rec.left + " right " + rec.right
//                + " top " + rec.top + " bottom " + rec.bottom
//
//                + "\n new left " + rect.left + " right " + rect.right
//                + " top " + rect.top + " bottom " + rect.bottom
//                + " rect width " + width + " rect height " + height
//
//                + "\n view getWidth " + getWidth() + " getHeight " + getHeight()
//                + "\n getDisplayMetrics width " + w + " height " + h
//                + "\n camera previewWidth " + mCameraManager.getPreviewWidth()
//                + " previewHeight " + mCameraManager.getPreviewHeight()
//        );
        return rect;
    }

    ///处理识别结果，
    // 头像照格式：{"Name":{"value":""}, "Sex":{"value":""},"Folk":{"value":""},
    // "Birt":{"value":""},"Addr":{"value":""},"Num":{"value":""} }
    //国徽照格式：{"Issue":{"value":""},"Valid":{"value":""},}
    private void handleResultCallback(String result, String imgPath, String headPath) {
        try {
            JSONObject json = new JSONObject(result);
            HashMap<String, Object> map = new HashMap<>();
            for (Iterator<String> iterator = json.keys(); iterator.hasNext(); ) {
                String key = iterator.next();
                String value = getValue(json, key);
                map.put(key.toLowerCase(), value);
            }
            map.put("imgPath", imgPath);
            map.put("headPath", headPath);
            if (mCallback != null) {
                mCallback.callback(map);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    /**
     * 拍照返回数据
     * @param imgPath 图片保存路径
     */
    private void handleResultCallback(String imgPath){
        HashMap<String, Object> map = new HashMap<>();
        map.put("imgPath", imgPath);
        if (mCallback != null) {
            mCallback.callback(map);
        }
    }

    private String getValue(JSONObject json, String key) throws JSONException {
        if (json != null && json.has(key)) {
            JSONObject value = json.optJSONObject(key);
            return value != null ? (String) value.opt("value") : null;
        }
        return null;
    }


    @Override
    public void surfaceCreated(@NonNull SurfaceHolder holder) {
        if (!mCameraManager.cameraOpened()) {
            mCameraManager.openCamera();
            setParameters();
        }
    }

    @Override
    public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {
        if (holder.getSurface() == null) {
            return;
        }
        mSurfaceHolder = holder;

        mCameraManager.setPreviewDisplay(mSurfaceHolder);
        mCameraManager.initDisplay();
        mHandler.sendEmptyMessageDelayed(OcrConstant.START_AUTOFOCUS, 500);
    }

    @Override
    public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
        mCameraManager.closeCamera();
        mSurfaceHolder = null;
    }

    private void onPreviewCallback(byte[] data){
        if(mThread == null || !mThread.isAlive()){
            mThread = new HandlerThread("savePicture");
            mThread.start();
            mThreadHandler  = new Handler(mThread.getLooper());
        }
        if(mThreadRun != null) mThreadHandler.removeCallbacks(mThreadRun);
        //线程处理数据
        mCameraManager.pauseDisplay();
        stopDecoding();
        File file = FilePathUtils.getFile(getContext(), mOcrImgFilePath, "ocr_img.jpg");
        mHandlingData = true;
        mThreadRun = new CustomOcrRectView2.PreviewDataRunnable(
                data,
                mCameraManager.getPreviewWidth(),
                mCameraManager.getPreviewHeight(),
                file,
                getImageRotation(),
                isTakePictureWithRect ? mUsedRect : null,
                () -> mMainHandler.postDelayed(() -> {
                    if (mCameraManager != null) {
                        mCameraManager.initDisplay();
                        startDecoding();
                    }
                    isTakePictureFromPreview = false;
                    isTakePictureWithRect = false;
                    mHandlingData = false;
                    handleResultCallback(file.getAbsolutePath());
                }, 350));//new TakePictureRun(data);
        mThreadHandler.post(mThreadRun);
    }

    private Thread mCameraOpenThread = new Thread(new Runnable() {
        public void run() {
            try {
                mCameraManager.openCamera();
            } catch (Exception e) {
                e.printStackTrace();
                mCameraError = true;
            }
        }
    });


    ///获取图片需要旋转角度
    private int getImageRotation(){
        if(!mUseOrientation)return portraitToLandscape ? 90 : 0;
        if(mOrientationListener == null)return 0;
        //mCameraManager.getCameraAngle()==90
//        后置摄像头/前置摄像头 后-竖向 后-横向 后-反竖向 后-反横向	前-竖向 前-横向 前-反竖向 前-反横向
//        getRotation	90	0	 270	180	 270	0	 90	 180
//        需要旋转角度	0	270	 180	90	 180	270	 0	 90
        int rotation = mOrientationListener.getRotation();
        switch (rotation){
            case 0: return 270; //后-横向、前-竖向
            case 90: return 0;//后-竖向、前-反竖向
            case 180: return 90;//后-反横向、前-反横向
            case 270: return 180;//后-反竖向、前-竖向
        }
        return 0;
    }

    ///是否是  后置摄像头
    private boolean isCameraFacingBack(){
        return mCameraManager.isCameraFacingBack();
    }

    ///当前手机 旋转角度
    private class MyOrientationEventListener extends OrientationEventListener {

        private int orientation;

        MyOrientationEventListener(Context context) {
            super(context);
        }

        @Override
        public void onOrientationChanged(int orientation) {
            if(orientation == ORIENTATION_UNKNOWN) {
               // OcrLogger.w("orientations", orientation);
                return;
            }
            this.orientation = orientation;
        }

        private int getRotation() {
            int rotation;
            if(orientation > 325 || orientation <= 45){
                rotation = isCameraFacingBack() ? 90 : 270;
            }else if(orientation <= 135){
                rotation = 180;
            }else if(orientation <= 225){
                rotation = isCameraFacingBack() ? 270 : 90;
            }else {
                rotation = 0;
            }
            OcrLogger.d("orientations", orientation,"use rotation",rotation);
            return rotation;
        }
    }
}
